package com.study.jdk.j8;

import org.junit.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;

/**
 * @author: jzhou
 * @date: 2024/12/1-15:35
 * @version: 1.0
 * @description: juc-study
 */
public class MapStudy {

    @Test
    public void testGetOrDefault() {
        Map<String, String> map = new HashMap<>(4);
        map.put("123", "123");
        String key = "key";
        String defaultValue = "defaultValue";

        String newValue = map.getOrDefault(key, defaultValue);
        System.out.println("getOrDefault " + newValue);
    }

    @Test
    public void testForeach() {
        Map<String, String> map = new HashMap<>(4);
        map.put("123", "123");

        map.forEach((key, value) -> System.out.printf("新写法 key = %s, value = %s%n", key, value));
    }

    @Test
    public void testMerge() {
        Map<String, Integer> cntMap = new HashMap<>(8);
        List<String> list = Arrays.asList("apple", "orange", "banana", "orange");

        // Integer::sum
        BiFunction<Integer, Integer, Integer> sumFunction = (oldValue, newValue) -> oldValue + newValue;
        for (String item : list) {
            cntMap.merge(item, 1, (oldValue, newValue) -> oldValue + newValue);
        }
        System.out.println(cntMap);
    }

    @Test
    public void testPutIfAbsent() {
        Map<String, Integer> scoreMap = new HashMap<>(4);
        scoreMap.put("Jim", 88);
        scoreMap.put("Lily", 90);

        scoreMap.putIfAbsent("Lily", 98); // 并没有更新
        System.out.println(scoreMap);
    }

    /**
     * 比 merge 更加灵活，因为可以拿到 key ，而 merge 只能对值进行操作
     */
    @Test
    public void testComputer() {
        Map<String, Integer> cntMap = new HashMap<>(8);
        List<String> list = Arrays.asList("apple", "orange", "banana", "orange");

        // 新写法
        for (String item : list) {
            cntMap.compute(item, (k, v) -> {
                if (v == null) {
                    v = 1;
                } else {
                    v += 1;
                }
                return v;
            });
        }
        System.out.println(cntMap);
    }

    /**
     * 递归调用,计算斐波那契
     */
    @Test
    public void testComputerIfAbsent() {
        Map<Integer, Integer> fabMap = new ConcurrentHashMap<>(16);
        fabMap.put(0, 1);
        fabMap.put(1, 1);
        System.out.println(fab(5, fabMap));
    }

    private Integer fab(Integer index, Map<Integer, Integer> fabMap) {
        return fabMap.computeIfAbsent(index, i -> fab(i - 2, fabMap) + fab(i - 1, fabMap));
    }

    @Test
    public void testReplace() {
        // 创建一个 HashMap
        Map<String, Integer> map = new HashMap<>();
        map.put("apple", 5);
        map.put("banana", 3);
        map.put("cherry", 7);

        // 使用 replace(K key, V value) 方法
        Integer oldValue = map.replace("banana", 10);
        System.out.println("Replaced banana's value: Old value = " + oldValue); // 输出: Replaced banana's value: Old value = 3

        // 尝试替换一个不存在的键
        oldValue = map.replace("grape", 20);
        System.out.println("Tried to replace grape's value: Old value = " + oldValue); // 输出: Tried to replace grape's value: Old value = null


        boolean wasReplaced = map.replace("cherry", 7, 15);
        System.out.println("Replaced cherry's value (7 to 15): " + wasReplaced); // 输出: Replaced cherry's value (7 to 15): true
        // 尝试用7替换cherry的当前值15，应该失败
        wasReplaced = map.replace("cherry", 7, 25);
        System.out.println("Tried to replace cherry's value (7 to 25): " + wasReplaced); // 输出: Tried to replace cherry's value (7 to 25): false

        // 使用 replaceAll(BiFunction<? super K, ? super V, ? extends V> function) 方法
        // 将所有值乘以2
        BiFunction<String, Integer, Integer> multiplyByTwo = (key, value) ->  value * 2;
        map.replaceAll(multiplyByTwo);

        // 打印结果
        System.out.println("Map after replaceAll: " + map); // 输出: Map after replaceAll: {apple=10, banana=20, cherry=30}
    }


}
